home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
demos
/
VGX
/
shadows
/
shadow_scn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
16KB
|
548 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
shadow_scn.c - Read a scene description from file, build data structures.
Tim Heidmann, Silicon Graphics
Created June 21, 1991
Last Edit November 25, 1991
*/
#include <stdio.h>
#include <gl.h>
#include <gl/image.h>
#include <device.h>
#include <math.h>
#include <string.h>
#include "shadows.h"
#include "glo_obj.h"
#include "vect.h"
/* Default shadowed and highlit material values */
#define MATEMISOFF 0
#define MATAMBIOFF 4
#define MATDIFFOFF 8
#define MATSPECOFF 12
#define MATSHINOFF 16
float defaultLitMaterial[] = {
EMISSION, 0.0, 0.0, 0.0,
AMBIENT, 0.2, 0.2, 0.2,
DIFFUSE, 0.8, 0.8, 0.8,
SPECULAR, 0.0, 0.0, 0.0,
SHININESS, 0.0,
LMNULL
};
float defaultShadowMaterial[] = {
EMISSION, 0.0, 0.0, 0.0,
AMBIENT, 0.2, 0.2, 0.2,
DIFFUSE, 0.0, 0.0, 0.0,
SPECULAR, 0.0, 0.0, 0.0,
SHININESS, 0.0,
LMNULL
};
float defaultHighMaterial[] = {
EMISSION, 0.0, 0.0, 0.0,
AMBIENT, 0.0, 0.0, 0.0,
DIFFUSE, 0.8, 0.8, 0.8,
SPECULAR, 0.0, 0.0, 0.0,
SHININESS, 0.0,
LMNULL
};
#define MATDEFLEN (sizeof(defaultHighMaterial)/sizeof(float))
#define LGTAMBOFF 0
#define LGTCOLOFF 4
#define LGTPOSOFF 8
#define LGTSPDOFF 13
#define LGTSPLOFF 17
float defaultLight[] = {
AMBIENT, 0.0, 0.0, 0.0,
LCOLOR, 1.0, 1.0, 1.0,
POSITION, 0.0, 0.0, 1.0, 0.0,
SPOTDIRECTION, 0.0, 0.0, -1.0,
SPOTLIGHT, 0.0, 180.0,
LMNULL
};
#define LGTDEFLEN (sizeof(defaultLight)/sizeof(float))
float defaultLight_posn[] = {0.0, 0.0, 10000.0};
float FlatGray[] = {
EMISSION, 0.0, 0.0, 0.0,
AMBIENT, 1.0, 1.0, 1.0,
DIFFUSE, 1.0, 1.0, 1.0,
SPECULAR, 0.0, 0.0, 0.0,
SHININESS, 20.0,
LMNULL
};
float FlatGrayA[] = {
EMISSION, 0.0, 0.0, 0.0,
AMBIENT, 1.0, 1.0, 1.0,
DIFFUSE, 0.0, 0.0, 0.0,
SPECULAR, 0.0, 0.0, 0.0,
SHININESS, 20.0,
LMNULL
};
float FlatGrayH[] = {
EMISSION, 0.0, 0.0, 0.0,
AMBIENT, 0.0, 0.0, 0.0,
DIFFUSE, 1.0, 1.0, 1.0,
SPECULAR, 0.0, 0.0, 0.0,
SHININESS, 20.0,
LMNULL
};
float RightRed[] = {
AMBIENT, 0.0, 0.0, 0.0,
LCOLOR, 1.0, 0.0, 0.0,
POSITION, 1.0, 1.0, 1.0, 0.0,
LMNULL
};
float LeftBlue[] = {
AMBIENT, 0.0, 0.0, 0.0,
LCOLOR, 0.0, 0.0, 1.0,
POSITION, -1.0, 1.0, 1.0, 0.0,
LMNULL
};
float theLModel[] = {
AMBIENT, 0.2, 0.2, 0.2,
LOCALVIEWER, 0.0,
ATTENUATION, 1.0, 0.0,
TWOSIDE, 0.0,
LMNULL
};
#define SS_UNDEFINED -1
#define SS_WINDOW 0
#define SS_LOOKAT 1
#define SS_MODEL 2
#define SS_XMODEL 17
#define SS_LIGHT 3
#define SS_POSITI 4
#define SS_ROTATI 5
#define SS_SCALE 6
#define SS_TEXTUR 18
#define SS_MATERI 7
#define SS_SPECUL 8
#define SS_SHININ 9
#define SS_DIFFUS 10
#define SS_EMISSI 11
#define SS_AMBIEN 12
#define SS_LCOLOR 13
#define SS_SPOTDI 14
#define SS_SPOTLI 15
#define SS_JITTER 19
#define SS_END 16
struct scmd_tag {
int index;
char *name;
} SceneCommands[] = {
{SS_WINDOW, "WIN" }, /* WINDOW height near far */
{SS_LOOKAT, "LOO" }, /* LOOKAT eyex eyey eyez gazex gazey gazez */
{SS_MODEL , "MOD" }, /* MODEL filename (shadow-casting model) */
{SS_XMODEL, "XMO" }, /* XMODEL filename (non shadow-casting model) */
{SS_LIGHT , "LIG" }, /* LIGHT <light properties...> END */
/* Light properties are AMBIENT, LCOLOR, */
/* POSITION, SPOTDIRECTION, and SPOTLIGHT. */
{SS_POSITI, "POS" }, /* POSITION x y z (for models) */
/* POSITION x y z w (for lights) */
{SS_ROTATI, "ROT" }, /* ROTATION xrot yrot zrot */
{SS_SCALE , "SCA" }, /* SCALE s */
{SS_TEXTUR, "TEX" }, /* TEXTURE filename */
{SS_MATERI, "MAT" }, /* MATERIAL <material properties...> END */
/* Material properties are EMISSION, AMBIENT,*/
/* DIFFUSE, SPECULAR, and SHININESS. */
{SS_SPECUL, "SPE" }, /* SPECULAR r g b (color components,0.0-1.0) */
{SS_SHININ, "SHI" }, /* SHININESS s (Specular exp, 0.0-128.0) */
{SS_DIFFUS, "DIF" }, /* DIFFUSE r g b */
{SS_EMISSI, "EMI" }, /* EMISSION r g b */
{SS_AMBIEN, "AMB" }, /* AMBIENT r g b */
{SS_LCOLOR, "LCO" }, /* LCOLOR r g b */
{SS_LCOLOR, "COL" }, /* COLOR r g b */
{SS_SPOTDI, "SPOTD"}, /* SPOTDIRECTION dx dy dz */
{SS_SPOTLI, "SPOTL"}, /* SPOTLIGHT exp spread */
/* (exponent 0.0-128.0, spread: 0.0-90.0) */
{SS_JITTER, "JIT" }, /* JITTER xrange yrange zrange */
{SS_END , "END" } /* END (for material or light def)*/
};
#define NSCENECMDS (sizeof(SceneCommands)/sizeof(struct scmd_tag))
PolyDataRec NullPolyData = {0, 0, NULL, NULL};
/* Forward declarations */
void
AddEdge(EdgePtr edgeList, int *nEdgesp, int v1, int v2, int thisFace,
int *iEdgep, int *iSidep);
PolyDataPtr
GetPolyData(glo_ObjPtr pdl);
InitScene() {
int i, done, localDone, count, theCommand;
int iTmp, iList[30], iMaterial, iTexture;
float fTmp[30], fLit[30], fHigh[30], fShad[30], x;
long *itex, xtex, ytex;
char cmd[60], objFileName[60];
FILE *inf;
/* Set flags and constant values */
vmatcopy(IdentMat, scene_rotMatrix);
iMaterial = 1;
iTexture = 1;
/* Read and parse the scene file, if specified */
if (sceneFileName != NULL) {
if ((inf = fopen(sceneFileName, "r")) == NULL) {
fprintf(stderr, "Cannot open scene file %s\n", sceneFileName);
exit(1);
}
fscanf(inf, "%s", cmd);
if (strcmp(cmd, "ShadowScene") != 0) {
fprintf(stderr, "File %s is not a Shadow Scene file.\n",
sceneFileName);
exit(1);
}
for (done = FALSE; !done; ) {
count = fscanf(inf, "%s", cmd);
if (count == EOF) {
done = TRUE;
continue;
}
switch (theCommand = FindCommand(cmd)) {
/* Camera, and view parameters */
case SS_WINDOW:
count = fscanf(inf, "%f %f %f", viewWindow, viewWindow+1,
viewWindow+2);
break;
case SS_LOOKAT:
count = fscanf(inf, "%f %f %f %f %f %f", eyex, eyex+1, eyex+2,
gazex, gazex+1, gazex+2);
break;
/* Model geometry and scene, model, light positioning */
case SS_MODEL:
case SS_XMODEL:
fscanf(inf, "%s", objFileName);
if ((obj_drawlist[nObjects]=glo_ReadObj(objFileName)) != NULL) {
/* We've got a glo_Object file. Get edge adjacency data. */
obj_data[nObjects] = (theCommand == SS_MODEL) ?
GetPolyData(obj_drawlist[nObjects]) :
&NullPolyData;
} else if (ReadPDataObj(objFileName,
obj_drawlist+nObjects, obj_data+nObjects)) {
/* Got a binary geometry & data file */
if (theCommand == SS_XMODEL) {
/* Remove any edge data for non-shadowing objects */
free(obj_data[nObjects]->faces);
obj_data[nObjects]->faces = NULL;
free(obj_data[nObjects]->edges);
obj_data[nObjects]->edges = NULL;
obj_data[nObjects]->nFaces = 0;
obj_data[nObjects]->nEdges = 0;
}
} else {
/* Cannot recognize this file */
fprintf(stderr, "Cannot open object file %s\n",
objFileName);
exit(1);
}
/* Initialize various parameters */
for (i=0; i<3; i++) obj_posn[nObjects][i] = 0.0;
obj_scale[nObjects] = 1.0;
vmatcopy(IdentMat, obj_rotMatrix[nObjects]);
obj_litMaterial[nObjects] = -1;
obj_texture[nObjects] = 0;
nObjects++;
break;
case SS_POSITI:
fscanf(inf, "%f %f %f", fTmp, fTmp+1, fTmp+2);
if (nObjects > 0)
for (i=0; i<3; i++)
obj_posn[nObjects-1][i] = fTmp[i];
break;
case SS_ROTATI:
fscanf(inf, "%f %f %f", fTmp, fTmp+1, fTmp+2);
if (nObjects <= 0)
GetRotMatrix(scene_rotMatrix, fTmp);
else
GetRotMatrix(obj_rotMatrix[nObjects-1], fTmp);
break;
case SS_SCALE:
fscanf(inf, "%f", fTmp);
if (nObjects > 0)
obj_scale[nObjects-1] = fTmp[0];
break;
case SS_MATERI:
/* Build lit, shadow, and hilite material definition arrays */
if (nObjects <= 0) {
fprintf(stderr,
"Material definition does not follow an object.\n");
exit(1);
}
for (i=0; i<MATDEFLEN; i++) fHigh[i]=defaultHighMaterial[i];
for (i=0; i<MATDEFLEN; i++) fShad[i]=defaultShadowMaterial[i];
for (i=0; i<MATDEFLEN; i++) fLit[i]=defaultLitMaterial[i];
for (localDone = FALSE; !localDone; ) {
fscanf(inf, "%s", cmd);
switch (FindCommand(cmd)) {
case SS_SPECUL:
fscanf(inf, "%f %f %f", fLit+MATSPECOFF+1,
fLit+MATSPECOFF+2, fLit+MATSPECOFF+3);
for (i=1; i<4; i++)
fHigh[MATSPECOFF+i] = fLit[MATSPECOFF+i];
break;
case SS_SHININ:
fscanf(inf, "%f", fLit+MATSHINOFF+1);
fHigh[MATSHINOFF+1] = fLit[MATSHINOFF+1];
break;
case SS_DIFFUS:
fscanf(inf, "%f %f %f", fLit+MATDIFFOFF+1,
fLit+MATDIFFOFF+2, fLit+MATDIFFOFF+3);
for (i=1; i<4; i++)
fHigh[MATDIFFOFF+i] = fLit[MATDIFFOFF+i];
break;
case SS_EMISSI:
fscanf(inf, "%f %f %f", fLit+MATEMISOFF+1,
fLit+MATEMISOFF+2, fLit+MATEMISOFF+3);
for (i=1; i<4; i++)
fShad[MATEMISOFF+i] = fLit[MATEMISOFF+i];
break;
case SS_AMBIEN:
fscanf(inf, "%f %f %f", fLit+MATAMBIOFF+1,
fLit+MATAMBIOFF+2, fLit+MATAMBIOFF+3);
for (i=1; i<4; i++)
fShad[MATAMBIOFF+i] = fLit[MATAMBIOFF+i];
break;
case SS_END:
lmdef(DEFMATERIAL,
obj_litMaterial[nObjects-1] = iMaterial++,
0, fLit);
lmdef(DEFMATERIAL,
obj_shadowMaterial[nObjects-1] = iMaterial++,
0, fShad);
lmdef(DEFMATERIAL,
obj_highMaterial[nObjects-1] = iMaterial++,
0, fHigh);
localDone = TRUE;
break;
default:
fprintf(stderr, "Unknown MATERIAL keyword: %s\n", cmd);
break;
}
}
break;
case SS_TEXTUR:
/* Read and define a texture */
if (nObjects <= 0) {
fprintf(stderr,
"Texture definition does not follow an object.\n");
exit(1);
}
fscanf(inf,"%s", cmd);
ReadImg(cmd, &itex, &xtex, &ytex);
texdef2d(obj_texture[nObjects-1] = iTexture++, 4,
xtex, ytex, itex, 0, tex_val);
free(itex);
break;
case SS_LIGHT:
/* Build a light definition array */
iTmp = 0;
for (i=0; i<3; i++) {
light_posn[nLights][i] = defaultLight_posn[i];
jitter_light_range[nLights][i] = 0.0;
}
for (i=0; i<LGTDEFLEN; i++) fTmp[i] = defaultLight[i];
for (localDone = FALSE; !localDone; ) {
fscanf(inf, "%s", cmd);
switch (FindCommand(cmd)) {
case SS_AMBIEN:
fscanf(inf, "%f %f %f", fTmp+LGTAMBOFF+1,
fTmp+LGTAMBOFF+2, fTmp+LGTAMBOFF+3);
break;
case SS_LCOLOR:
fscanf(inf, "%f %f %f", fTmp+LGTCOLOFF+1,
fTmp+LGTCOLOFF+2, fTmp+LGTCOLOFF+3);
break;
case SS_POSITI:
fscanf(inf, "%f %f %f %f", fTmp+LGTPOSOFF+1,
fTmp+LGTPOSOFF+2, fTmp+LGTPOSOFF+3,
fTmp+LGTPOSOFF+4);
x = fabs(fTmp[LGTPOSOFF+4]) < 0.01 ?
0.01 : fTmp[LGTPOSOFF+4];
for (i=0; i<3; i++)
light_posn[nLights][i] = fTmp[LGTPOSOFF+1+i]/x;
break;
case SS_SPOTDI:
fscanf(inf, "%f %f %f", fTmp+LGTSPDOFF+1,
fTmp+LGTSPDOFF+2, fTmp+LGTSPDOFF+3);
break;
case SS_SPOTLI:
fscanf(inf, "%f %f %f", fTmp+LGTSPLOFF+1,
fTmp+LGTSPLOFF+2, fTmp+LGTSPLOFF+3);
break;
case SS_JITTER:
fscanf(inf, "%f %f %f", jitter_light_range[nLights],
jitter_light_range[nLights] + 1,
jitter_light_range[nLights] + 2);
break;
case SS_END:
lmdef(DEFLIGHT, nLights+1, 0, fTmp);
localDone = TRUE;
break;
default:
fprintf(stderr, "Unknown LIGHT keyword: %s\n", cmd);
break;
}
}
nLights++;
break;
case SS_END:
done = TRUE;
break;
default:
fprintf(stderr, "Unknown keyword: %s\n", cmd);
break;
}
}
}
/* Set defaults where unspecified */
if (nObjects <= 0) {
/* If no objects defined, put three cubes in */
for (nObjects = 0; nObjects < 3; nObjects++) {
obj_drawlist[nObjects] = &glo_cube;
obj_data[nObjects] = GetPolyData(obj_drawlist[nObjects]);
vmatcopy(IdentMat, obj_rotMatrix[nObjects]);
obj_litMaterial[nObjects] = -1;
}
vset(obj_posn[0], 1.35, -0.78, 0.0);
vset(fTmp, 20.0, 5.0, 17.0);
GetRotMatrix(obj_rotMatrix[0], fTmp);
obj_scale[0] = 1.0;
vset(obj_posn[1], -1.35, -0.78, 0.0);
vset(fTmp, -5.0, 35.0, -35.0);
GetRotMatrix(obj_rotMatrix[1], fTmp);
obj_scale[1] = 1.2;
vset(obj_posn[2], 0.00, 1.56, 0.0);
vset(fTmp, -19.0, 5.0, 5.0);
GetRotMatrix(obj_rotMatrix[2], fTmp);
obj_scale[2] = 1.4;
}
/* Assign a gray material to any undefined objects */
lmdef(DEFMATERIAL, iMaterial, 0, FlatGray);
lmdef(DEFMATERIAL, iMaterial+1, 0, FlatGrayA);
lmdef(DEFMATERIAL, iMaterial+2, 0, FlatGrayH);
for (i=0; i<nObjects; i++)
if (obj_litMaterial[i] < 0) {
obj_litMaterial[i] = iMaterial;
obj_shadowMaterial[i] = iMaterial+1;
obj_highMaterial[i] = iMaterial+2;
}
/* If no lights defined, put in a red one and a blue one */
if (nLights <= 0) {
lmdef(DEFLIGHT, 1, 0, RightRed);
lmdef(DEFLIGHT, 2, 0, LeftBlue);
nLights = 2;
vset(light_posn[0], 100.0, 100.0, 100.0);
vset(light_posn[1], -100.0, 100.0, 100.0);
vset(jitter_light_range[0], 10.0, 10.0, 10.0);
vset(jitter_light_range[1], 5.0, 5.0, 5.0);
}
/* Define the light model */
lmdef(DEFLMODEL, 1, 0, theLModel);
lmbind(LMODEL, 1);
}
int
FindCommand(char buf[]) {
int i;
for (i=0; i<NSCENECMDS; i++)
if (strncmp(buf, SceneCommands[i].name,
strlen(SceneCommands[i].name)) == 0)
return SceneCommands[i].index;
return SS_UNDEFINED;
}
int
GetRotMatrix(Matrix aMatrix, float r[]) {
/* Use GL hardware to get composite rotation matrix */
pushmatrix();
loadmatrix(IdentMat);
rot(r[0], 'x');
rot(r[1], 'y');
rot(r[2], 'z');
getmatrix(aMatrix);
popmatrix();
}
int
ReadImg(char *filename, long **pbgImage, int *pbgXsize, int *pbgYsize) {
register IMAGE *image;
register int x, y, xsize, ysize;
register int z, zsize;
short buf[4096];
if ((image=iopen(filename, "r")) == NULL ) {
fprintf(stderr,"readimg: can't open input file %s\n",filename);
return FALSE;
}
xsize = image->xsize;
ysize = image->ysize;
zsize = image->zsize;
if(zsize<3) {
fprintf(stderr,"readimg: this is not an RGB image file\n");
return FALSE;
}
*pbgImage = (long *) malloc(xsize * ysize * sizeof(long));
*pbgXsize = xsize; *pbgYsize = ysize;
for(y=0; y<ysize; y++) {
getrow(image,buf,y,0); /* Red */
for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] = buf[x] | 0xff000000;
getrow(image,buf,y,1); /* Green */
for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] |= buf[x] << 8;
getrow(image,buf,y,2); /* Blue */
for (x=0; x<xsize; x++) (*pbgImage)[y*xsize + x] |= buf[x] << 16;
}
return TRUE;
}